package com.meme.editor.model.sprite2d;

import com.meme.editor.property.Property;
import com.meme.util.XmlUtil;
import com.meme.util.FileUtil;
import com.meme.editor.EntityObject;

import java.util.Vector;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;

public class Sprite2dFile extends EntityObject
{
	static Logger logger = Logger.getLogger (Sprite2dFile.class);
	
	public static final String EntityName_ModuleImageSet = "Module Images";
	public static final String EntityName_PureModuleGroupSet = "Pure Module Groups";
	public static final String EntityName_CompositedModuleGroupSet = "Composited Module Groups";
	public static final String EntityName_AnimatedModuleGroupSet = "Animated Module Groups";
	public static final String EntityName_ProdefinedModelSet = "Predefined Models";
	public static final String EntityName_TilePaletteSet = "Tile Palettes";
	public static final String EntityName_TiledBackgroundSet = "Tiled Backgrounds";
	
	//
	
	public class ModuleImageSet extends EntityObject
	{
		protected ModuleImageSet () 
		{
			super (EntityName_ModuleImageSet); 
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}		
		
		@Override protected boolean isValidChild (EntityObject entity) 
		{ 
			return entity instanceof ModuleImage; 
		}
	}
	
	public class PureModuleGroupSet extends EntityObject
	{
		public PureModuleGroupSet () 
		{ 
			super (EntityName_PureModuleGroupSet); 
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof PureModuleGroup;
		}
	}
	
	public class CompositedModuleGroupSet extends EntityObject
	{
		public CompositedModuleGroupSet ()
		{
			super (EntityName_CompositedModuleGroupSet);
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof CompositedModuleGroup;
		}
	}
	
	public class AnimatedModuleGroupSet extends EntityObject
	{
		public AnimatedModuleGroupSet ()
		{
			super (EntityName_AnimatedModuleGroupSet);
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof AnimatedModuleGroup;
		}
	}
	
	public class ModelSet extends EntityObject
	{
		public ModelSet ()
		{
			super (EntityName_ProdefinedModelSet);
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof Sprite2dModel;
		}
	}
	
	public class TilePaletteSet extends EntityObject
	{
		public TilePaletteSet ()
		{
			super (EntityName_TilePaletteSet);
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof Tiled2dGrid;
		}
	}

	public class TiledBackgroundSet extends ModuleGroup // EntityObject
	{
		public TiledBackgroundSet ()
		{
			super (EntityName_TiledBackgroundSet);
			getPublicProperty (EntityObject.GroupName_Entity, EntityObject.PropertyName_Name).setEditable(false);
		}
		
		@Override
		protected boolean isValidChild (EntityObject entity)
		{
			return entity instanceof Tiled2dBackground;
		}
	}

	
//---------------------------------------------------------------------------------------
// categories
//---------------------------------------------------------------------------------------
	
	
	// the categories
	ModuleImageSet mModuleImageSet = new ModuleImageSet ();
	PureModuleGroupSet mPureModuleGroupSet = new PureModuleGroupSet ();
	CompositedModuleGroupSet mCompositedModuleGroupSet = new CompositedModuleGroupSet ();
	AnimatedModuleGroupSet mAnimationGroupSet = new AnimatedModuleGroupSet ();

	TilePaletteSet mTilePaletteSet = new TilePaletteSet ();
	TiledBackgroundSet mTiledBackgroundSet = new TiledBackgroundSet ();

	ModelSet mPredefinedModelSet = new ModelSet ();

	public ModuleImageSet getModuleImageSet ()
	{
		return mModuleImageSet;
	}
	
	public PureModuleGroupSet getPureModuleGroupSet ()
	{
		return mPureModuleGroupSet;
	}
	
	public CompositedModuleGroupSet getCompositedModuleGroupSet ()
	{
		return mCompositedModuleGroupSet;
	}
	
	public AnimatedModuleGroupSet getAnimatedModuleGroupSet ()
	{
		return mAnimationGroupSet;
	}
	
	public ModelSet getPredefinedModelSet ()
	{
		return mPredefinedModelSet;
	}
	
	public TilePaletteSet getTilePaletteSet ()
	{
		return mTilePaletteSet;
	}
	
	public TiledBackgroundSet getTiledBackgroundSet ()
	{
		return mTiledBackgroundSet;
	}
	

	public ModuleImage createNewModuleImage ()
	{
		ModuleImage moduleimage = new ModuleImage ();
		mModuleImageSet.addChild(moduleimage);
		
		return moduleimage;
	}
	
	public PureModuleGroup createNewPureModuleGroup ()
	{
		PureModuleGroup modulegroup = new PureModuleGroup ();
		mPureModuleGroupSet.addChild(modulegroup);
		
		return modulegroup;
	}
		
	public CompositedModuleGroup createNewCompositedModuleGroup ()
	{
		CompositedModuleGroup modulegroup = new CompositedModuleGroup ();
		mCompositedModuleGroupSet.addChild(modulegroup);
		
		return modulegroup;
	}
		
	public AnimatedModuleGroup createNewAnimatedModuleGroup ()
	{
		AnimatedModuleGroup animationgroup = new AnimatedModuleGroup ();
		mAnimationGroupSet.addChild (animationgroup);
		
		return animationgroup;
	}
	
	public Sprite2dModel createNewModel ()
	{
		Sprite2dModel model = new Sprite2dModel ();
		mPredefinedModelSet.addChild (model);
		
		return model;
	}
	
	public Tiled2dPalette createNewTilePalette ()
	{
		Tiled2dPalette grid = new Tiled2dPalette ();
		mTilePaletteSet.addChild (grid);
		
		return grid;
	}
	
	public Tiled2dBackground createNewTiledBackground ()
	{
		Tiled2dBackground tiledBg = new Tiled2dBackground ();
		mTiledBackgroundSet.addChild (tiledBg);
		
		return tiledBg;
	}
	

//---------------------------------------------------------------------------------------
// constructors
//---------------------------------------------------------------------------------------


	public Sprite2dFile ()
	{
		super ("unnamed");

		
		addChild (mModuleImageSet);
		addChild (mPureModuleGroupSet);
		addChild (mCompositedModuleGroupSet);
		addChild (mAnimationGroupSet);
		addChild (mTilePaletteSet);
		addChild (mTiledBackgroundSet);
		addChild (mPredefinedModelSet);
	}


	public static String getFileExtension ()
	{
		return "xSprite2d";
	}

//---------------------------------------------------------------------------------------
// override some funcitons
//---------------------------------------------------------------------------------------
	
	@Override
	public boolean isHostObject ()
	{
		return true;
	}
	
	@Override
	public void setHostFilename (String filename)
	{
		super.setHostFilename (filename);
		
		setName (FileUtil.getFilenameWithoutExt(filename));
	}
	
	
	@Override
	public String getDefaultName ()
	{
		return "Sprite";
	}
	
	
//---------------------------------------------------------------------------------------
// helper funcitons
//---------------------------------------------------------------------------------------
	
	// for children, chidren of children, ..., to find the Sprited2dFile hosted in 
	public static Sprite2dFile getSprite2dFileHostedIn (EntityObject descendant)
	{
		logger.assertLog(descendant != null, "descendant can't be null.");
		
		EntityObject parent = descendant;
		while ( parent != null )
		{
			if ( parent instanceof Sprite2dFile )
				return (Sprite2dFile)parent;
			
			parent = parent.getParent();
		}
		
		return null;
	}
	
}
